﻿using CrawlerApp.Core.Entities;
using CrawlerApp.Core.Entities.BookAggregate;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text.Json;

namespace CrawlerApp.Infrastructure.Data.Config
{
    public class BookConfiguration : IEntityTypeConfiguration<Book>
    {
        public void Configure(EntityTypeBuilder<Book> builder)
        {
            builder.HasIndex(b => b.Name)
                .IsUnique();

            builder.Property(b => b.Name)
                .IsRequired()
                .HasMaxLength(50);

            builder.HasIndex(b => b.Href)
                .IsUnique();

            builder.Property(b => b.Href)
                .IsRequired()
                .HasMaxLength(500);

            builder.Property(b => b.Intro)
                .HasMaxLength(500);

            builder.Property(b => b.Cover)
                .HasMaxLength(500);

            builder.Property<bool>("Deleted")
                .HasDefaultValue(false);
            builder.HasQueryFilter(b => !EF.Property<bool>(b, "Deleted"));

            builder.OwnsOne(b => b.Vote, a =>
            {
                a.WithOwner();

                a.Property(a => a.Great)
                  .IsRequired()
                  .HasDefaultValue(0);
                a.Property(a => a.Good)
                  .IsRequired()
                  .HasDefaultValue(0);
                a.Property(a => a.Normal)
                  .IsRequired()
                  .HasDefaultValue(0);
                a.Property(a => a.Worse)
                  .IsRequired()
                  .HasDefaultValue(0);
                a.Property(a => a.Bad)
                  .IsRequired()
                  .HasDefaultValue(0);
            });

            builder.OwnsOne(b => b.Resource, r =>
              {
                  r.WithOwner();

                  r.Ignore(r => r.Urls);

                  var converter = new ValueConverter<List<string>, string>(
                      v => string.Join(',', v),
                      v => v.Split(new char[] { ',' }).ToList());

                  r.Property<List<string>>("_urls")
                  .HasColumnName($"{nameof(Book.Resource)}_Urls")
                  .HasConversion(converter);

                  //r.Property<string>("_urls")
                  //.HasColumnName($"{nameof(Book.Resource)}_Urls");

                  r.Property(r => r.Verifer)
                  .HasMaxLength(50);

                  r.Property(r => r.Length)
                  .HasMaxLength(50);

                  r.Property(r => r.Progress)
                  .HasMaxLength(50);
              });

            builder.HasMany(x => x.Tags)
                .WithMany(x => x.Books)
                .UsingEntity<Dictionary<string, object>>(
                "BookTag",
                b => b.HasOne<Tag>()
                    .WithMany()
                    .OnDelete(DeleteBehavior.ClientSetNull)
                    .HasForeignKey("TagId"),
                b => b.HasOne<Book>()
                    .WithMany()
                    .OnDelete(DeleteBehavior.Cascade)
                    .HasForeignKey("BookId"));
        }
    }
}
